﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "CmdCreateArcByCenterEndPtGridNew.h"

#include "GmUiStructureCommandRegister.h"
#include "StructureCmdIds.h"
#include "GbmpModelViewTypes.h"
#include "GbmpControlIds.h"
#include "GridNewInput.h"
#include "IGridNew.h"
#include "GbmpModelViewUtil.h"
#include "GbmpUiPlatformUtils.h"

#include "IModelView.h"
#include "IPlane.h"
#include "UiCommonDialog.h"
#include "AddStructureDynamicPannelUtil.h"
#include "DrawArcByCenterEndPtElementBehavior.h"
#include "IDocument.h"
#include "ILine2d.h"
#include "IArc2d.h"
#include "IUserTransaction.h"
#include "IUiView.h"
#include "GcmpActionBase.h"
#include "IGenericElement.h"
#include "GbmpPresetParameterUIUtils.h"
#include "UserTransactionGroupUtils.h"
#include "IGraphicsElementShape.h"
#include "GridNewUtils.h"
#include "UiDocumentViewUtils.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"


using namespace gcmp;

REGISTER_GM_COMMAND(CmdCreateArcByCenterEndPtGridNew)

CmdCreateArcByCenterEndPtGridNew::CmdCreateArcByCenterEndPtGridNew()
    : CmdCreateArcByCenterEndPtElement(ID_CMD_DRAWING_ARC_GRIDNEW_BYCENTER)
{
    m_utxGroupIdx = 0;
}

bool CmdCreateArcByCenterEndPtGridNew::OnExecuteCommand()
{
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    const std::wstring& viewType = pModelView->GetUserDataId();

    if (PlanViewType != viewType)
    {
        UiCommonDialog::ShowMessageBox(GBMP_TR(L"创建轴网"), GBMP_TR(L"此视图下不支持创建轴网"), (int)UiCommonDialog::ButtonType::OK);
        return false;
    }

    return true;
}

void CmdCreateArcByCenterEndPtGridNew::SetupRibbonContextualPanel()
{
    AddStructureDynamicPannelUtil::SetupGridNewCreationContext(m_pDrawArcByCenterEndPtAction, ID_PAGE_GBMP_MODIFY);
}

OwnerPtr<DrawArcByCenterEndPtElementBehavior> CmdCreateArcByCenterEndPtGridNew::CreateDrawArcByCenterEndPtElementBehavior()
{
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    OwnerPtr<DrawArcByCenterEndPtElementBehavior> opGridNewBehavior = NEW_AS_OWNER_PTR(DrawArcByCenterEndPtElementBehavior, pDoc);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opGridNewBehavior, L"opGridNewBehavior为空",L"GDMPLab",L"2024-03-30");

    opGridNewBehavior->SetOnFinishCallback(DrawArcByCenterEndPtElementBehavior::CreateOnFinishCallback(&CmdCreateArcByCenterEndPtGridNew::OnArcFinish, this));

    return TransferOwnership(opGridNewBehavior);
}

bool CmdCreateArcByCenterEndPtGridNew::CreatePresetElement(ElementId& elementId)
{
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    GridNewInput gridNewInput;
    gridNewInput.Document = pDoc;
    gridNewInput.Visible = false;
    OwnerPtr<IPlane> opIPlane = pModelView->GetWorkPlane();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opIPlane, L"opIPlane为空",L"GDMPLab",L"2024-03-30");
    gridNewInput.verticalExtents = GridNewUtils::GetGridDefaultVerticalExtents(pDoc, opIPlane.get(), ElementCreationOptions::Transient);
    GridNewUtils::setGridNewPresetParameter(pDoc,gridNewInput.StartTagVisble, gridNewInput.EndTagVisble);
    gridNewInput.CreationOption = ElementCreationOptions::Transient;

    // 创建临时的线用来刷新属性面板
    OwnerPtr<ICurve2d> opCurve = ILine2d::Create(Vector2d(0.0, 0.0), Vector2d(1.0, 0.0));
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opCurve, L"opArc为空",L"GDMPLab",L"2024-03-30");
    gridNewInput.VecOpCurve.push_back(TransferOwnership(opCurve));

    // 创建预设轴网
    IGridNew* pPresetGridNew = IGridNew::Create(gridNewInput);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetGridNew, L"pPresetGridNew为空",L"GDMPLab",L"2024-03-30");
    //获取除了轴号的属性面板参数   
    elementId = pPresetGridNew->GetOwnerElement()->GetElementId();
    return true;
}

bool CmdCreateArcByCenterEndPtGridNew::OnArcFinish(IUiView* pCurrentView, const Vector3d& centerPt, const Vector3d& startPt, const Vector3d& endPt)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pCurrentView, L"pCurrentView为空",L"GDMPLab",L"2024-03-30");

    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    IPlane* pPlane = pModelView->GetWorkPlane().get();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPlane, L"pPlane为空",L"GDMPLab",L"2024-03-30");

    GridNewInput gridNewInput;
    gridNewInput.Document = pDoc;
    gridNewInput.verticalExtents = GridNewUtils::GetGridDefaultVerticalExtents(pDoc, pPlane, ElementCreationOptions::Normal);
    GridNewUtils::setGridNewPresetParameter(pDoc,gridNewInput.StartTagVisble, gridNewInput.EndTagVisble);
    gridNewInput.Visible = true;
    gridNewInput.CreationOption = ElementCreationOptions::Normal;

    // 将三维坐标点转化为平面上的二维点
    ElementId planeId = GbmpModelViewUtil::GetWorkLevelId(pCurrentView->GetModelView());
    Coordinate3d planeCoord = GbmpUiPlatformUtils::GetPlaneCoordinate3d(pDoc, planeId);
    Vector2d centerPtLocal = planeCoord.GetLocalPointXY(centerPt);
    Vector2d startPtLocal = planeCoord.GetLocalPointXY(startPt);
    Vector2d endPtLocal = planeCoord.GetLocalPointXY(endPt);

    // 利用平面向量的叉乘，判断两个向量之间夹角是顺时针还是逆时针
    bool antiClockwise = false;
    Vector2d startVec = startPtLocal - centerPtLocal;
    Vector2d endVec = endPtLocal - centerPtLocal;
    double crossResult = startVec.Cross(endVec);
    if (crossResult > 0)
    {
        antiClockwise = true;
    }
    OwnerPtr<IArc2d> opArc = IArc2d::Create(centerPtLocal, startPtLocal, endPtLocal, antiClockwise);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opArc, L"opArc为空",L"GDMPLab",L"2024-03-30");
    gridNewInput.VecOpCurve.push_back(TransferOwnership(opArc));

    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(pDoc, GBMP_TR(L"创建轴网"));
    // 根据gridNewInput提供的参数创建轴网
    
    IGridNew* pGridNew = IGridNew::Create(gridNewInput);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pGridNew, L"pGridNew为空",L"GDMPLab",L"2024-03-30");

    // 获取预设轴网的ElementId
    ElementId presetGridId = m_pDrawArcByCenterEndPtAction->GetPreSetElementId();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(presetGridId.IsValid(), L"presetGridElement为空",L"GDMPLab",L"2024-03-30");
    IElement *presetGridElement = pDoc->GetElement(presetGridId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(presetGridElement, L"presetGridElement为空",L"GDMPLab",L"2024-03-30");
    IGenericElement* pPresetGenericElement = quick_cast<IGenericElement>(presetGridElement);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetGenericElement, L"pPresetGenericElement为空",L"GDMPLab",L"2024-03-30");
    IGridNew* pPresetGrid = quick_cast<IGridNew>(pPresetGenericElement->GetExternalObject());

    // 根据属性面板中的轴网Name更新当前绘制的轴网Name
    pGridNew->SetName(pPresetGrid->GetName());

    // 设置预设轴网的下一个名字并刷新属性面板
    pPresetGrid->AutoName();
    GbmpPresetParameterUIUtils::UpdatePropertyPanel(presetGridId);

    // 提交事务
    ut->Commit();
    // 提交事务组并合并为一个事务
    UserTransactionGroupUtils::CommitLatestActiveWithTransactionsMergedIntoOne(UiDocumentViewUtils::GetCurrentDocument());
    // 启动新的事务组
    UserTransactionGroupUtils::Start(UiDocumentViewUtils::GetCurrentDocument(), GBMP_TR(L"创建单条轴网事务组"), m_utxGroupIdx);

    return true;
}

bool CmdCreateArcByCenterEndPtGridNew::OnRadiusUpdate(IUiView* pCurrentView, const Vector3d& firstPt, const Vector3d& pos,
    OwnerPtr<IGraphicsElementShape>& opGElementShape)
{
    return false;
}

bool CmdCreateArcByCenterEndPtGridNew::OnArcUpdate(IUiView* pCurrentView, const Vector3d& centerPt, const Vector3d& startPt, const Vector3d& pos,
    OwnerPtr<IGraphicsElementShape>& opGElementShape)
{
    return false;
}
